/// \file RendererDX11.h
/// \date 2012-12-08
/// \brief concrete class that offers the rendering and graphics device related functionality in DX11

#ifndef _TORUSPRORENDERING_RENDER_RENDERERDX11_H__
#define _TORUSPRORENDERING_RENDER_RENDERERDX11_H__

// DirectX11
#include <d3d11.h>
#include <D3dx9math.h>


#include <Render/Include/Renderer.h>
#include <Render/Include/IWinWindow.h>

namespace Render
{

    /// \brief concrete class that offers the rendering and graphics device related functionality in DX11
    class RendererDX11 : public Renderer
    {
    public:
        // ========== LIFECYCLE ========== //

        /// \brief Constructor
        RendererDX11(IWinWindow* window);

        /// \brief Destructor
        virtual ~RendererDX11();

        // ========== OVERLODED OPERATORS ========== //

        // ========== METHODS ========== //

        /// \brief concrete method to render a torus
        virtual void renderTorus(AppModel::Torus* torus);

        /// \brief concrete method to create a texture
        virtual Texture* createTexture(const char* file);

        /// \brief concrete method to create a mesh
        virtual Mesh* createMesh(VertexData* vertex_data, const unsigned int &vertex_count, IndexData* index_data, const unsigned int &index_count);


        // ========== GETTERS ========== //

        // ========== SETTERS ========== //

        // ========== INQUIRY ========== //

    private:
        /// \brief data to configure the transformation constant buffer
        typedef struct
        {
            D3DXMATRIX world;
            D3DXMATRIX view;
            D3DXMATRIX projection;
            D3DXMATRIX normal;
            D3DXVECTOR4 wave_offset;            
        }ConstantBufferTransformationData;

        /// \brief data to configure the lighting constant buffer
        typedef struct
        {
            D3DXVECTOR3 light_dir;
            float material_specular_power;
            D3DXVECTOR4 light_color;
            D3DXVECTOR4 ambient_material_color;
            D3DXVECTOR4 diffuse_material_color;
            D3DXVECTOR4 specular_material_color;            
        }ConstantBufferLightingData;
        // ========== INTERNAL METHODS ========== //

        /// \brief function used to compile a shader
        bool compileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut );

        std::wstring convertToWideString(const std::string &cadena);

        // ========== ATTRIBUTES ========== //

        /// \brief directX11 device 
        ID3D11Device*  device;

        /// \brief directX11 immediate context 
        ID3D11DeviceContext* immediate_context;

        /// \brief directX11 swap chain 
        IDXGISwapChain* swap_chain;

        /// \brief directX11 render target
        ID3D11RenderTargetView* render_target_view;

        /// \brief directX11 depth stencil
        ID3D11DepthStencilView* depth_stencil_view;

        /// \brief directX11 viewport
        D3D11_VIEWPORT viewport;

        /// \brief directX11 vertex shader
        ID3D11VertexShader* vertex_shader;

        /// \brief directX11 pixel shader
        ID3D11PixelShader* pixel_shader;

        /// \brief directX11 vertex input layout
        ID3D11InputLayout* input_layout;

        /// \brief directX11 constant buffer pointer
        ID3D11Buffer* constant_buffer_transformation;

        ID3D11Buffer* constant_buffer_lighting;

        /// \brief directX11 sampler texture state
        ID3D11SamplerState* sampler_state;

    };
};
#endif // _TORUSPRORENDERING_RENDER_RENDERERDX11_H__
